<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-CN">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Microsoft YaHei:300,300italic,400,400italic,700,700italic|Microsoft YaHei:300,300italic,400,400italic,700,700italic|Microsoft YaHei:300,300italic,400,400italic,700,700italic|Microsoft YaHei:300,300italic,400,400italic,700,700italic|Inziu Iosevka Slab SC:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.2" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="Hexo, NexT" />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.2" />






<meta name="description" content="Digital signal processingDomains: Time and space domains, Frequency domain, Z-plane analysis, Wavelet">
<meta property="og:type" content="article">
<meta property="og:title" content="Digital Signal Processing">
<meta property="og:url" content="http://idmk.oschina.io/2018/02/27/Digital-Signal-Processing/index.html">
<meta property="og:site_name" content="苦舟">
<meta property="og:description" content="Digital signal processingDomains: Time and space domains, Frequency domain, Z-plane analysis, Wavelet">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://idmk.oschina.io/2018/02/27/Digital-Signal-Processing/markdown-img-paste-20180227134113422.png">
<meta property="og:image" content="http://idmk.oschina.io/2018/02/27/Digital-Signal-Processing/2018-03-21-22-46-27.png">
<meta property="og:image" content="http://idmk.oschina.io/2018/02/27/Digital-Signal-Processing/2018-03-21-20-59-30.png">
<meta property="og:updated_time" content="2018-02-27T03:09:26.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Digital Signal Processing">
<meta name="twitter:description" content="Digital signal processingDomains: Time and space domains, Frequency domain, Z-plane analysis, Wavelet">
<meta name="twitter:image" content="http://idmk.oschina.io/2018/02/27/Digital-Signal-Processing/markdown-img-paste-20180227134113422.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    sidebar: {"position":"left","display":"hide","offset":12,"offset_float":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: true,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://idmk.oschina.io/2018/02/27/Digital-Signal-Processing/"/>





  <title>Digital Signal Processing | 苦舟</title>
  














</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">苦舟</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">学海无涯，吾将上下求索。</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-commonweal">
          <a href="/404.html" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br />
            
            公益404
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://idmk.oschina.io/2018/02/27/Digital-Signal-Processing/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="东木金">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/uploads/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苦舟">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">Digital Signal Processing</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-02-27T11:09:26+08:00">
                2018-02-27
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p><a href="https://en.wikipedia.org/wiki/Digital_signal_processing" target="_blank" rel="external">Digital signal processing</a><br>Domains: Time and space domains, Frequency domain, Z-plane analysis, Wavelet<br><a id="more"></a></p>
<h1 id="基础频谱分析"><a href="#基础频谱分析" class="headerlink" title="基础频谱分析"></a>基础频谱分析</h1><h2 id="频谱分析变量"><a href="#频谱分析变量" class="headerlink" title="频谱分析变量"></a>频谱分析变量</h2><table>
<thead>
<tr>
<th style="text-align:center">变量名称</th>
<th style="text-align:center">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">x</td>
<td style="text-align:center">采样的数据</td>
</tr>
<tr>
<td style="text-align:center">n = length(x)</td>
<td style="text-align:center">样本数量</td>
</tr>
<tr>
<td style="text-align:center">Fs</td>
<td style="text-align:center">采样频率（每单位时间或空间的样本数）</td>
</tr>
<tr>
<td style="text-align:center">dt = 1/Fs</td>
<td style="text-align:center">每样本的时间或空间增量</td>
</tr>
<tr>
<td style="text-align:center">t = (0:n-1)/Fs</td>
<td style="text-align:center">数据的时间或空间范围</td>
</tr>
<tr>
<td style="text-align:center">y = fft(x)</td>
<td style="text-align:center">数据的离散傅里叶变换 (DFT)</td>
</tr>
<tr>
<td style="text-align:center">abs(y)</td>
<td style="text-align:center">DFT 的振幅</td>
</tr>
<tr>
<td style="text-align:center">(abs(y).^2)/n</td>
<td style="text-align:center">DFT 的幂</td>
</tr>
<tr>
<td style="text-align:center">Fs/n</td>
<td style="text-align:center">频率增量</td>
</tr>
<tr>
<td style="text-align:center">f = (0:n-1)*(Fs/n)</td>
<td style="text-align:center">频率范围</td>
</tr>
<tr>
<td style="text-align:center">Fs/2</td>
<td style="text-align:center">Nyquist 频率（频率范围的中点）</td>
</tr>
</tbody>
</table>
<h2 id="对噪声信号做频谱分析"><a href="#对噪声信号做频谱分析" class="headerlink" title="对噪声信号做频谱分析"></a>对噪声信号做频谱分析</h2><figure class="highlight matlab"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="comment">% 创建具有 15 Hz 和 40 Hz 分量频率的信号，并插入随机高斯噪声。</span></div><div class="line">fs = <span class="number">100</span>;                                <span class="comment">% sample frequency (Hz)</span></div><div class="line">t = <span class="number">0</span>:<span class="number">1</span>/fs:<span class="number">10</span><span class="number">-1</span>/fs;                      <span class="comment">% 10 second span time vector</span></div><div class="line">x = (<span class="number">1.3</span>)*<span class="built_in">sin</span>(<span class="number">2</span>*<span class="built_in">pi</span>*<span class="number">15</span>*t) ...             <span class="comment">% 15 Hz component</span></div><div class="line">  + (<span class="number">1.7</span>)*<span class="built_in">sin</span>(<span class="number">2</span>*<span class="built_in">pi</span>*<span class="number">40</span>*(t<span class="number">-2</span>)) ...         <span class="comment">% 40 Hz component</span></div><div class="line">  + <span class="number">2.5</span>*<span class="built_in">gallery</span>(<span class="string">'normaldata'</span>,<span class="built_in">size</span>(t),<span class="number">4</span>); <span class="comment">% Gaussian noise;</span></div><div class="line">y = fft(x);</div><div class="line"><span class="comment">% 将功率频谱绘制为频率的函数。尽管噪声在基于时间的空间内伪装成信号的频率分量，但傅里叶变换将其显现为功率尖峰。</span></div><div class="line">n = <span class="built_in">length</span>(x);          <span class="comment">% number of samples</span></div><div class="line">f = (<span class="number">0</span>:n<span class="number">-1</span>)*(fs/n);     <span class="comment">% frequency range</span></div><div class="line">power = <span class="built_in">abs</span>(y).^<span class="number">2</span>/n;    <span class="comment">% power of the DFT</span></div><div class="line">plot(f,power)</div><div class="line">xlabel(<span class="string">'Frequency'</span>)</div><div class="line">ylabel(<span class="string">'Power'</span>)</div></pre></td></tr></table></figure>
<h2 id="fftshift"><a href="#fftshift" class="headerlink" title="fftshift"></a>fftshift</h2><p>在许多应用中，查看以 0 频率为中心的功率频谱更加方便，因为它能更好地显示信号的周期性。使用 fftshift 函数对 y 执行循环平移，并绘制以 0 为中心的功率。<br><figure class="highlight matlab"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="comment">% 创建具有 15 Hz 和 40 Hz 分量频率的信号，并插入随机高斯噪声。</span></div><div class="line">fs = <span class="number">100</span>;                                <span class="comment">% sample frequency (Hz)</span></div><div class="line">t = <span class="number">0</span>:<span class="number">1</span>/fs:<span class="number">10</span><span class="number">-1</span>/fs;                      <span class="comment">% 10 second span time vector</span></div><div class="line">x = (<span class="number">1.3</span>)*<span class="built_in">sin</span>(<span class="number">2</span>*<span class="built_in">pi</span>*<span class="number">15</span>*t) ...             <span class="comment">% 15 Hz component</span></div><div class="line">  + (<span class="number">1.7</span>)*<span class="built_in">sin</span>(<span class="number">2</span>*<span class="built_in">pi</span>*<span class="number">40</span>*(t<span class="number">-2</span>)) ...         <span class="comment">% 40 Hz component</span></div><div class="line">  + <span class="number">2.5</span>*<span class="built_in">gallery</span>(<span class="string">'normaldata'</span>,<span class="built_in">size</span>(t),<span class="number">4</span>); <span class="comment">% Gaussian noise;</span></div><div class="line">y = fft(x);</div><div class="line">n = <span class="built_in">length</span>(x);          <span class="comment">% number of samples</span></div><div class="line">y0 = fftshift(y);         <span class="comment">% shift y values</span></div><div class="line">f0 = (-n/<span class="number">2</span>:n/<span class="number">2</span><span class="number">-1</span>)*(fs/n); <span class="comment">% 0-centered frequency range</span></div><div class="line">power0 = <span class="built_in">abs</span>(y0).^<span class="number">2</span>/n;    <span class="comment">% 0-centered power</span></div><div class="line">plot(f0,power0)</div><div class="line">xlabel(<span class="string">'Frequency'</span>)</div><div class="line">ylabel(<span class="string">'Power'</span>)</div></pre></td></tr></table></figure></p>
<h2 id="逆向快速傅里叶变换"><a href="#逆向快速傅里叶变换" class="headerlink" title="逆向快速傅里叶变换"></a>逆向快速傅里叶变换</h2><p><a href="https://cn.mathworks.com/help/matlab/ref/ifft.html" target="_blank" rel="external">ifft</a></p>
<h1 id="滤波器设计"><a href="#滤波器设计" class="headerlink" title="滤波器设计"></a>滤波器设计</h1><p>数字滤波器从功能上可以分为低通、高通、带通和带阻滤波器，根据数字滤波器冲激响应的时域特性，可将数字滤波器分为两种，即无限长冲激响应（IIR）滤波器和有限长冲激响应（FIR）滤波器。</p>
<h2 id="实际滤波器的设计指标"><a href="#实际滤波器的设计指标" class="headerlink" title="实际滤波器的设计指标"></a>实际滤波器的设计指标</h2><p>当滤波器形状为非理想时，要用一些参数指标来描述其关键特性。<br>滤波器的通带定义了滤波器允许通过的频率范围。在阻带内，滤波器对信号严重衰减。$W_p$  和 $W_s$ 分别称为通带截止频率（或通带上限频率）和阻带截止频率（或阻带下限频率）。<br>参数 $\theta_1$ 定义了通带波纹，即滤波器通带内偏移单位增益的最大值。参数 $\theta_2$ 定义了阻带波纹，即滤波器阻带内偏离零增益的最大值。<br>参数 $\beta_t$ 定义了过渡带宽度，即阻带下限和通带上限之间的距离，$\beta_t = |W_p  - W_s|$ 。过渡带一般是单调下降的，通带内和阻带内允许的衰减一般用单位 $dB$ 表示，通带内允许的最大衰减用 $\alpha_p$ 表示，阻带内允许的最小衰减用 $\alpha_s$ 表示，它们分别定义为</p>
<p>$\alpha_p = 20 lg(A_{max}/A_{min}) = 20 lg ((1+\theta_1)/(1-\theta_1))dB$<br>$\alpha_s = 20 lg(A_{max}/A_s) = 20 lg ((1+\theta_1)/(\theta_2))dB$</p>
<p>式中，$A_{max}$ 是通带内的幅度最大值；$A_{min}$ 是通带内的幅度最小值，$A_s$ 是阻带内最大值。幅度下降到 0.707 即 $\dfrac {\sqrt {2}}{2}$ 时，$w=w_c$ ，此时 $\alpha_p =3dB$，称 $w_c$ 为 3dB 通带截止频率。</p>
<h2 id="FIR-滤波器简介"><a href="#FIR-滤波器简介" class="headerlink" title="FIR 滤波器简介"></a>FIR 滤波器简介</h2><p>FIR 系统只有零点，因此这类系统不像 IIR 系统那样易取得比较好的通带和阻带衰减特性。但 FIR 系统有自己突出的优点，其一是系统总是稳定的，其二是易实现线性相位，其三是允许设计多通带（或多阻带）滤波器。<br>FIR 滤波器是指系统的单位冲击响应 $h(n)$ 仅在有限的范围内有非零值的滤波器。N-1 阶滤波器的系统函数 H(z) 可表示为<br>$$H\left( z\right) =\sum ^{N-1}_{n=0}h\left( n\right) z^{-n}$$</p>
<p>$H(z)$ 是 $z^{-1}$ 的 N-1 次多项式，它在 z 平面上有 N-1 个零点，原点 z=0 是 N-1 阶重极点。因此，FIR 滤波器永远稳定。</p>
<p>FIR 滤波器的频率响应为<br>$$H\left( e^{i\omega }\right) =\sum ^{N-1}_{n=1}h\left( n\right) e^{-i\omega n}$$<br>由于 $H\left( e^{in}\right)$ 一般为复数，因此，可将其表示成：<br>$$H\left( e^{iw}\right) =\left| H\left( e^{iw}\right) \right| e^{i\theta \left( w\right) }$$</p>
<h3 id="FIR-滤波器的线性相位特性"><a href="#FIR-滤波器的线性相位特性" class="headerlink" title="FIR 滤波器的线性相位特性"></a>FIR 滤波器的线性相位特性</h3><p>$H\left( e^{in}\right)$ 线性相位特性是指 $\theta \left( w\right)$ 是 $w$ 的线性函数，即<br>$$\theta \left( w\right) =-\alpha w$$<br>式中， $\alpha$ 是常数。此时通过这一系统的各频率分量的时延为相同的常数，系统的群时延为<br>$$\tau <em>{g}=-\dfrac {d\theta \left( W\right) }{d\omega }=\alpha$$<br>即系统的时延是一个与 $w$ 无关的常数 $\alpha$ ，称系统 $H(z)$ 具有严格的线性相位。<br>由于严格线性相位条件在数学上处理较为困难，因此在 FIR 滤波器设计中一般使用广义线性相位。若一个离散系统的频率响应 $H\left( e^{iw}\right)$ 可以写为<br>$$H\left( e^{i\omega }\right) =H</em>{g}\left( w\right) e^{i(-\alpha w+\beta)}=H_{h}\left( w\right) e^{i\cdot \left( w\right) }$$</p>
<p>……</p>
<p><a href="基于 matlab 的 FIR 数字滤波器设计及其软件实现 .doc">基于 matlab 的 FIR 数字滤波器设计及其软件实现 .doc</a></p>
<h2 id="fir1-Window-based-FIR-filter-design"><a href="#fir1-Window-based-FIR-filter-design" class="headerlink" title="fir1: Window-based FIR filter design"></a>fir1: Window-based FIR filter design</h2><p><strong>Syntax</strong><br><figure class="highlight matlab"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">b = fir1(n,Wn)</div><div class="line">b = fir1(n,Wn,ftype)</div><div class="line">b = fir1(___,window)</div><div class="line">b = fir1(___,scaleopt)</div></pre></td></tr></table></figure></p>
<p><strong>Description</strong><br><code>b = fir1(n,Wn)</code> uses a Hamming window to design an nth-order lowpass, bandpass, or multiband FIR filter with linear phase. The filter type depends on the number of elements of Wn.<br><code>b = fir1(n,Wn,ftype)</code> designs a lowpass, highpass, bandpass, bandstop, or multiband filter, depending on the value of ftype and the number of elements of Wn.<br><code>b = fir1(___,window)</code> designs the filter using the vector specified in window and any of the arguments from previous syntaxes.<br><code>b = fir1(___,scaleopt)</code> additionally specifies whether or not the magnitude response of the filter is normalized.</p>
<h3 id="输入参数"><a href="#输入参数" class="headerlink" title="输入参数"></a>输入参数</h3><h4 id="n-—-Filter-order-integer-scalar"><a href="#n-—-Filter-order-integer-scalar" class="headerlink" title="n — Filter order, integer scalar"></a>n — Filter order, integer scalar</h4><p>Filter order, specified as an integer scalar.</p>
<p>For highpass and bandstop configurations, fir1 always uses an even filter order. The order must be even because odd-order symmetric FIR filters must have zero gain at the Nyquist frequency. If you specify an odd n for a highpass or bandstop filter, then fir1 increments n by 1.</p>
<h4 id="Wn-—-Frequency-constraints-scalar-two-element-vector-multi-element-vector"><a href="#Wn-—-Frequency-constraints-scalar-two-element-vector-multi-element-vector" class="headerlink" title="Wn — Frequency constraints, scalar | two-element vector | multi-element vector"></a>Wn — Frequency constraints, scalar | two-element vector | multi-element vector</h4><p>Frequency constraints, specified as a scalar, a two-element vector, or a multi-element vector. All elements of Wn must be strictly greater than 0 and strictly smaller than 1, where 1 corresponds to the Nyquist frequency: 0 &lt; Wn &lt; 1. The Nyquist frequency is half the sample rate or π rad/sample.</p>
<p>If Wn is a scalar, then fir1 designs a lowpass or highpass filter with cutoff frequency Wn. The cutoff frequency is the frequency at which the normalized gain of the filter is – 6 dB.</p>
<p>If Wn is the two-element vector [w1 w2], where w1 &lt; w2, then fir1 designs a bandpass or bandstop filter with lower cutoff frequency w1 and higher cutoff frequency w2.</p>
<p>If Wn is the multi-element vector [w1 w2 … wn], where w1 &lt; w2 &lt; … &lt; wn, then fir1 returns an nth-order multiband filter with bands 0 &lt; ω &lt; w1, w1 &lt; ω &lt; w2,  … , wn &lt; ω &lt; 1.</p>
<h4 id="ftype-—-Filter-type-‘low’-‘bandpass’-‘high’-‘stop’-‘DC-0’-‘DC-1’"><a href="#ftype-—-Filter-type-‘low’-‘bandpass’-‘high’-‘stop’-‘DC-0’-‘DC-1’" class="headerlink" title="ftype — Filter type, ‘low’ | ‘bandpass’ | ‘high’ | ‘stop’ | ‘DC-0’ | ‘DC-1’"></a>ftype — Filter type, ‘low’ | ‘bandpass’ | ‘high’ | ‘stop’ | ‘DC-0’ | ‘DC-1’</h4><p>Filter type, specified as one of the following:<br>‘low’ specifies a lowpass filter with cutoff frequency Wn. ‘low’ is the default for scalar Wn.<br>‘high’ specifies a highpass filter with cutoff frequency Wn.<br>‘bandpass’ specifies a bandpass filter if Wn is a two-element vector. ‘bandpass’ is the default when Wn has two elements.<br>‘stop’ specifies a bandstop filter if Wn is a two-element vector.<br>‘DC-0’ specifies that the first band of a multiband filter is a stopband. ‘DC-0’ is the default when Wn has more than two elements.<br>‘DC-1’ specifies that the first band of a multiband filter is a passband.</p>
<h2 id="fir2-Frequency-sampling-based-FIR-filter-design"><a href="#fir2-Frequency-sampling-based-FIR-filter-design" class="headerlink" title="fir2: Frequency sampling-based FIR filter design"></a>fir2: Frequency sampling-based FIR filter design</h2><h1 id="Bilinear-transform"><a href="#Bilinear-transform" class="headerlink" title="Bilinear transform"></a>Bilinear transform</h1><p><a href="https://en.wikipedia.org/wiki/Bilinear_transform" target="_blank" rel="external">Bilinear transform</a><br><a href="https://zh.wikipedia.org/wiki/%E9%9B%99%E7%B7%9A%E6%80%A7%E8%BD%89%E6%8F%9B" target="_blank" rel="external">双线性转换</a><br>在数字信号处理和离散时间的控制理论中，双线性变换 ( 即 Tustin 变换 ) 被用来在连续时间系统与离散时间系统做转换。</p>
<h1 id="Linear-time-invariant-theory"><a href="#Linear-time-invariant-theory" class="headerlink" title="Linear time-invariant theory"></a>Linear time-invariant theory</h1><p><a href="https://en.wikipedia.org/wiki/Linear_time-invariant_theory" target="_blank" rel="external">Linear time-invariant theory</a><br><a href="https://zh.wikipedia.org/wiki/%E7%BA%BF%E6%80%A7%E6%97%B6%E4%B8%8D%E5%8F%98%E7%B3%BB%E7%BB%9F%E7%90%86%E8%AE%BA" target="_blank" rel="external">线性非时变系统理论</a><br>顾名思义，线性非时变系统必须同时满足线性和非时变性：<br>线性，指系统的输入和输出之间的关系是一个线性映射：如果输入 x 1 ( t ) {\displaystyle x<em>{1}(t)\,} x</em>{1}(t)\, 产生响应 y 1 ( t ) {\displaystyle y<em>{1}(t)\,} y</em>{1}(t)\,，而输入 x 2 ( t ) {\displaystyle x<em>{2}(t)\,} x</em>{2}(t)\, 产生响应 y 2 ( t ) {\displaystyle y<em>{2}(t)\,} y</em>{2}(t)\,，那么放缩和加和输入 a 1 x 1 ( t ) + a 2 x 2 ( t ) {\displaystyle a<em>{1}x</em>{1}(t)+a<em>{2}x</em>{2}(t)\,} a<em>{1}x</em>{1}(t)+a<em>{2}x</em>{2}(t)\, 产生放缩、加和的响应 a 1 y 1 ( t ) + a 2 y 2 ( t ) {\displaystyle a<em>{1}y</em>{1}(t)+a<em>{2}y</em>{2}(t)\,} a<em>{1}y</em>{1}(t)+a<em>{2}y</em>{2}(t)\,，其中 a 1 {\displaystyle a<em>{1}} a</em>{1} 和 a 2 {\displaystyle a_{2}} a_2 为实标量。</p>
<h2 id="重要的系统特性"><a href="#重要的系统特性" class="headerlink" title="重要的系统特性"></a>重要的系统特性</h2><p>因果性和稳定性是描述系统的两个重要性质。如果独立变量是时间，那么因果性是必须的，但并不是所有系统的独立变量都是时间。例如，一个处理静止图像的系统不需要具备因果性。非因果系统可以建立，并可以在许多情况下发挥作用。即使是非实数系统也可以构建，并且在很多场合也是非常有用的。</p>
<h3 id="因果性"><a href="#因果性" class="headerlink" title="因果性"></a>因果性</h3><p>如果系统输出只与当前以及过去的输入有关，那么该系统就是因果系统。</p>
<h3 id="稳定性"><a href="#稳定性" class="headerlink" title="稳定性"></a>稳定性</h3><p>如果系统对每个有界输入来说输出都是有界的，那么系统就是有界输入有界输出稳定的（BIBO 稳定）。</p>
<h2 id="离散时间系统"><a href="#离散时间系统" class="headerlink" title="离散时间系统"></a>离散时间系统</h2><p>几乎所有的连续时间系统都能找到与之对应的离散时间系统。</p>
<h3 id="连续时间系统中的离散时间系统"><a href="#连续时间系统中的离散时间系统" class="headerlink" title="连续时间系统中的离散时间系统"></a>连续时间系统中的离散时间系统</h3><p>在许多情况下，离散时间（DT）系统实际上是较大的连续时间（CT）系统的一部分。例如，数字录音系统记录模拟声音、数字化、或许对数字信号进行处理、然后重放模拟信号。</p>
<p>正式场合下所研究的离散时间信号几乎总是连续时间信号的均匀采样。如果 x ( t ) {\displaystyle x(t)} x(t) 是一个连续时间信号，那么模数转换器将把它转换成离散时间信号 x [ n ] {\displaystyle x[n]} x[n]，</p>
<pre><code>x [ n ] = x ( n T ) {\displaystyle x[n]=x(nT)} x[n]=x(nT),
</code></pre><p>其中 T 是采样周期。为了保证离散信号能够忠实地表示输入信号，非常重要的一点就是需要限制输入信号的频率范围。根据采样定理，离散时间信号所包括的最大频率范围是 1 / ( 2 T ) {\displaystyle 1/(2T)} 1/(2T)。其它频率都成为这个范围的混叠信号。</p>
<h2 id="冲激响应"><a href="#冲激响应" class="headerlink" title="冲激响应"></a>冲激响应</h2><p>如果我们给系统输入一个离散δ函数，由于δ函数是一个理想的脉冲，所以系统的线性时不变变换就是冲激响应。</p>
<h1 id="傅里叶分析"><a href="#傅里叶分析" class="headerlink" title="傅里叶分析"></a>傅里叶分析</h1><p><a href="https://zh.wikipedia.org/wiki/%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2" target="_blank" rel="external">傅里叶变换</a><br><a href="https://zh.wikipedia.org/wiki/%E7%A6%BB%E6%95%A3%E6%97%B6%E9%97%B4%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2" target="_blank" rel="external">离散时间傅里叶变换</a><br>傅里叶分析最初是研究周期性现象，即傅里叶级数的，后来通过傅里叶变换将其推广到了非周期性现象。理解这种推广过程的一种方式是将非周期性现象视为周期性现象的一个特例，即其周期为无限长。</p>
<h2 id="Fourier-series-傅里叶级数"><a href="#Fourier-series-傅里叶级数" class="headerlink" title="Fourier series 傅里叶级数"></a>Fourier series 傅里叶级数</h2><p>连续形式的傅里叶变换其实是傅里叶级数（Fourier series）的推广，因为积分其实是一种极限形式的求和算子而已。</p>
<h2 id="Discrete-time-Fourier-Transform"><a href="#Discrete-time-Fourier-Transform" class="headerlink" title="Discrete-time Fourier Transform"></a>Discrete-time Fourier Transform</h2><p>在数学中，离散时间傅里叶变换（DTFT，Discrete-time Fourier Transform）是傅里叶分析的一种形式，适用于连续函数的均匀间隔采样。离散时间是指对采样间隔通常以时间为单位的离散数据（样本）的变换。仅根据这些样本，它就可以产生原始连续函数的连续傅里叶变换的周期求和的以频率为变量的函数。在采样定理所描述的一定理论条件下，可以由 DTFT 完全恢复出原来的连续函数，因此也能从原来的离散样本恢复。DTFT 本身是频率的连续函数，但可以通过离散傅里叶变换（DFT）很容易计算得到它的离散样本（参见对 DTFT 采样），而 DFT 是迄今为止现代傅里叶分析最常用的方法。</p>
<h3 id="DTFT-与-DFT"><a href="#DTFT-与-DFT" class="headerlink" title="DTFT 与 DFT"></a>DTFT 与 DFT</h3><p>DFT（离散傅里叶变换）是对离散周期信号的一种傅里叶变换，对于有限长信号，则相当于对其周期延拓进行变换。在频域上，DFT 的离散谱是对 DTFT 连续谱的等间隔采样。</p>
<h1 id="Fast-Fourier-transform"><a href="#Fast-Fourier-transform" class="headerlink" title="Fast Fourier transform"></a>Fast Fourier transform</h1><p>A fast Fourier transform (FFT) is an algorithm that samples a signal over a period of time (or space) and divides it into its frequency components.[1] These components are single sinusoidal oscillations at distinct frequencies each with their own amplitude and phase. This transformation is illustrated in Diagram 1. Over the time period measured, the signal contains 3 distinct dominant frequencies.</p>
<img src="/2018/02/27/Digital-Signal-Processing/markdown-img-paste-20180227134113422.png" alt="Diagram 1: View of a signal in the time and frequency domain" title="Diagram 1: View of a signal in the time and frequency domain">
<p>快速傅里叶变换（英语：Fast Fourier Transform, FFT），是快速计算序列的离散傅里叶变换（DFT）或其逆变换的方法</p>
<p>FFT 会通过把 DFT 矩阵分解为稀疏（大多为零）因子之积来快速计算此类变换。[2] 因此，它能够将计算 DFT 的复杂度从只用 DFT 定义计算需要的 O ( n 2 ) {\displaystyle O(n^{2})} O(n^{2})，降低到 O ( n log ⁡ n ) {\displaystyle O(n\log n)} O(n\log n)，其中 n {\displaystyle n} n 为数据大小。</p>
<h1 id="Python-滤波器设计"><a href="#Python-滤波器设计" class="headerlink" title="Python 滤波器设计"></a>Python 滤波器设计</h1><h2 id="用-freqz-计算数字滤波器的频率响应"><a href="#用-freqz-计算数字滤波器的频率响应" class="headerlink" title="用 freqz 计算数字滤波器的频率响应"></a>用 freqz 计算数字滤波器的频率响应</h2><p><code>freqz(b, a=1, worN=None, whole=0, plot=None)</code><br>其中 b 和 a 是滤波器的系数，worN 为所计算的频率点数，whole 为 0 表示计算频率的上限为 pi，whole 为 1 表示计算频率的上限为 2*pi。</p>
<p>它返回一个组元 (w,h) ，其中 w 为所有计算了响应的频率数组，其值为正规化的圆频率，因此通过 w/(2<em>pi) 可以计算出对应的正规化频率。h 是一个复数数组，它表示滤波器系统在每个对应的频率点的响应。复数的幅值表示滤波器的增益特性，相角表示滤波器的相位特性。<br>程序中使用 freqz 计算滤波器的频率响应，并用 20</em>np.log10(np.abs(h)) 计算 h 以 dB 衡量的幅值。</p>
<p>如下图所示，这是一个低通滤波器，通过的频率为幅值高的频率区域，被阻断的是幅值低的频率区域。<br><img src="/2018/02/27/Digital-Signal-Processing/2018-03-21-22-46-27.png" alt="2018-03-21-22-46-27.png" title=""></p>
<h2 id="FIR-滤波器设计"><a href="#FIR-滤波器设计" class="headerlink" title="FIR 滤波器设计"></a>FIR 滤波器设计</h2><h3 id="理想的低通滤波器"><a href="#理想的低通滤波器" class="headerlink" title="理想的低通滤波器"></a>理想的低通滤波器</h3><p>理想的低通滤波器频率响应如下图所示：<br><img src="/2018/02/27/Digital-Signal-Processing/2018-03-21-20-59-30.png" alt="理想低通滤波器的频率响应" title="理想低通滤波器的频率响应"><br>其中 $f_s$ 为取样频率， $f_c$ 为阻带频率。通常为了计算方便，将取样频率正规化为 1。于是 $f_c$ 的含义就是每个取样点所包含的信号的周期数，例如 0.1 表示每个取样点包含 0.1 个周期，即一个周期有 10 个取样点。</p>
<h3 id="理想低通滤波器的近似方法"><a href="#理想低通滤波器的近似方法" class="headerlink" title="理想低通滤波器的近似方法"></a>理想低通滤波器的近似方法</h3><h4 id="用-firwin-设计滤波器"><a href="#用-firwin-设计滤波器" class="headerlink" title="用 firwin 设计滤波器"></a>用 firwin 设计滤波器</h4><p>SciPy 提供了 remez 窗函数设计低通滤波器，remez 的调用形式如下：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">remez(numtaps, bands, desired,</div><div class="line">    weight=<span class="keyword">None</span>, Hz=<span class="number">1</span>, type=<span class="string">'bandpass'</span>, maxiter=<span class="number">25</span>, grid_density=<span class="number">16</span>)</div></pre></td></tr></table></figure></p>
<p>其中：</p>
<ul>
<li>numtaps : 所设计的 FIR 滤波器的长度</li>
<li>bands ： 一个递增序列，它包括频率响应中的所有频带的边界，其值在 0 到 Hz/2 之间，如果参数 Hz 为缺省值 1 的话，那么可以把它当作是以取样频率正规化的频率</li>
<li>desired : 长度为 bands 的一半的增益序列，它给出频率响应在 bands 中的每个频带的增益值</li>
<li>weight : 长度和 desired 一样的权重序列，它给出 desired 中的每个增益所占的权重，即给出 desired 中的每个增益的重要性，值越大表示其越重要</li>
<li>type : ‘bandpass’ 或者 ‘differentiator’，本书只介绍 type 为 ‘bandpass’ 的情况</li>
</ul>
<p>当 numtaps 为偶数时，所设计的滤波器对于取样频率 /2 的响应为 0，因此无法设计出长度为偶数的高通滤波器。<br>程序中，remez 函数的 bands 参数给出两个频带 ( 以取样频率正规化 )：0 到 0.18 和 0.2 到 0.5，而 desired 给出两个频带的增益分别为 0.01 和 1，因此它所设计的是一个通带频率为 0.2、阻带增益为 -40dB 的高通滤波器。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="comment">## -*- coding: utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> scipy.signal <span class="keyword">as</span> signal</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> pl</div><div class="line"></div><div class="line"><span class="keyword">for</span> length <span class="keyword">in</span> [<span class="number">11</span>, <span class="number">31</span>, <span class="number">51</span>, <span class="number">101</span>, <span class="number">201</span>]:</div><div class="line">    b = signal.remez(length, (<span class="number">0</span>, <span class="number">0.19</span>,  <span class="number">0.21</span>,  <span class="number">0.50</span>), (<span class="number">0.01</span>, <span class="number">1</span>))</div><div class="line">    w, h = signal.freqz(b, <span class="number">1</span>)</div><div class="line">    pl.plot(w/<span class="number">2</span>/np.pi, <span class="number">20</span>*np.log10(np.abs(h)), label=str(length))</div><div class="line">pl.legend()</div><div class="line">pl.xlabel(<span class="string">u" 正规化频率 周期 / 取样 "</span>)</div><div class="line">pl.ylabel(<span class="string">u" 幅值 (dB)"</span>)</div><div class="line">pl.title(<span class="string">u"remez 设计高通滤波器 - 滤波器长度和频响的关系 "</span>)</div><div class="line">pl.show()</div></pre></td></tr></table></figure>
<h2 id="数字滤波器的计算工作"><a href="#数字滤波器的计算工作" class="headerlink" title="数字滤波器的计算工作"></a>数字滤波器的计算工作</h2><p>scipy 的 signal 库中提供了 lfilter 函数完成数字滤波器的计算工作。由于它是在 C 语言级别实现的，因此处理速度相当快：<br><code>signal.lfilter(b, a, x, axis=-1, zi=None)</code></p>
<p>当使用 lfilter 对很长的输入进行滤波计算时，不能一次把数据都读入到数组 x 中，因此需要对数据进行分段滤波，这时就需要将上一次调用 lfilter 时返回的数组 zf，传递到下一次 lfilter 函数调用。下面的程序演示了这种分段滤波的方法：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -*- coding: utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> scipy.signal <span class="keyword">as</span> signal</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> pl</div><div class="line"></div><div class="line"><span class="comment"># 某个均衡滤波器的参数</span></div><div class="line">a = np.array([<span class="number">1.0</span>, <span class="number">-1.947463016918843</span>, <span class="number">0.9555873701383931</span>])</div><div class="line">b = np.array([<span class="number">0.9833716591860479</span>, <span class="number">-1.947463016918843</span>, <span class="number">0.9722157109523452</span>])</div><div class="line"></div><div class="line"><span class="comment"># 44.1kHz， 1 秒的频率扫描波</span></div><div class="line">t = np.arange(<span class="number">0</span>, <span class="number">0.5</span>, <span class="number">1</span>/<span class="number">44100.0</span>)</div><div class="line">x= signal.chirp(t, f0=<span class="number">10</span>, t1 = <span class="number">0.5</span>, f1=<span class="number">1000.0</span>)</div><div class="line"></div><div class="line"><span class="comment"># 直接一次计算滤波器的输出</span></div><div class="line">y = signal.lfilter(b, a, x)</div><div class="line"></div><div class="line"><span class="comment"># 将输入信号分为 50 个数据一组</span></div><div class="line">x2 = x.reshape((<span class="number">-1</span>,<span class="number">50</span>))</div><div class="line"></div><div class="line"><span class="comment"># 滤波器的初始状态为 0， 长度是滤波器系数长度 -1</span></div><div class="line">z = np.zeros(max(len(a),len(b))<span class="number">-1</span>, dtype=np.float)</div><div class="line">y2 = [] <span class="comment"># 保存输出的列表</span></div><div class="line"></div><div class="line"><span class="keyword">for</span> tx <span class="keyword">in</span> x2:</div><div class="line">    <span class="comment"># 对每段信号进行滤波，并更新滤波器的状态 z</span></div><div class="line">    ty, z = signal.lfilter(b, a, tx, zi=z)</div><div class="line">    <span class="comment"># 将输出添加到输出列表中</span></div><div class="line">    y2.append(ty)</div><div class="line">    </div><div class="line"><span class="comment"># 将输出 y2 转换为一维数组</span></div><div class="line">y2 = np.array(y2)</div><div class="line">y2 = y2.reshape((<span class="number">-1</span>,))</div><div class="line"></div><div class="line"><span class="comment"># 输出 y 和 y2 之间的误差</span></div><div class="line">print(np.sum((y-y2)**<span class="number">2</span>))</div><div class="line"></div><div class="line"><span class="comment"># 绘图</span></div><div class="line">pl.plot(t, y, t, y2)</div><div class="line">pl.show()</div></pre></td></tr></table></figure></p>
<h2 id="滤波器级联"><a href="#滤波器级联" class="headerlink" title="滤波器级联"></a>滤波器级联</h2><p>假设有两个滤波器 h1 和 h2，我们将 h1 的输出输入到 h2，这样得到的滤波器称为 h1 和 h2 的级联。级联后的滤波器的脉冲响应为 h1 和 h2 的脉冲响应的卷积，而其频率响应为两个滤波器的频率响应的乘积。</p>
<h3 id="将低通滤波器和高通滤波器级联为带通滤波器"><a href="#将低通滤波器和高通滤波器级联为带通滤波器" class="headerlink" title="将低通滤波器和高通滤波器级联为带通滤波器"></a>将低通滤波器和高通滤波器级联为带通滤波器</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -*- coding: utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> scipy.signal <span class="keyword">as</span> signal</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> pl</div><div class="line"></div><div class="line">h1 = signal.remez(<span class="number">201</span>, (<span class="number">0</span>, <span class="number">0.18</span>,  <span class="number">0.2</span>,  <span class="number">0.50</span>), (<span class="number">0.01</span>, <span class="number">1</span>))</div><div class="line">h2 = signal.remez(<span class="number">201</span>, (<span class="number">0</span>, <span class="number">0.38</span>,  <span class="number">0.4</span>,  <span class="number">0.50</span>), (<span class="number">1</span>, <span class="number">0.01</span>))</div><div class="line">h3 = np.convolve(h1, h2)</div><div class="line"></div><div class="line">w, h = signal.freqz(h3, <span class="number">1</span>)</div><div class="line">pl.plot(w/<span class="number">2</span>/np.pi, <span class="number">20</span>*np.log10(np.abs(h)))</div><div class="line"></div><div class="line">pl.legend()</div><div class="line">pl.xlabel(<span class="string">u" 正规化频率 周期 / 取样 "</span>)</div><div class="line">pl.ylabel(<span class="string">u" 幅值 (dB)"</span>)</div><div class="line">pl.title(<span class="string">u" 低通和高通级联为带通滤波器 "</span>)</div><div class="line">pl.show()</div></pre></td></tr></table></figure>
<p>其等同于<br><code>h4 = signal.remez(201, (0, 0.18, 0.2, 0.38, 0.4, 0.50), (0.01, 1, 0.01))</code></p>
<p>但 h3 的长度几乎是 h4 的两倍。</p>
<h2 id="对采用频率为1000hz的信号做滤波处理"><a href="#对采用频率为1000hz的信号做滤波处理" class="headerlink" title="对采用频率为1000hz的信号做滤波处理"></a>对采用频率为1000hz的信号做滤波处理</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -*- coding: utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> scipy.signal <span class="keyword">as</span> signal</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"></div><div class="line">t = np.arange(<span class="number">0</span>, <span class="number">2</span>, <span class="number">1</span>/<span class="number">1000</span>)</div><div class="line">x1 = np.sin(<span class="number">2</span>*<span class="number">2</span>*np.pi*t)</div><div class="line">x2 = np.sin(<span class="number">4</span>*<span class="number">2</span>*np.pi*t)</div><div class="line">x = x1 + x2</div><div class="line"></div><div class="line">b = signal.remez(<span class="number">1000</span>, (<span class="number">0</span>, <span class="number">0.004</span>,  <span class="number">0.004</span>,  <span class="number">0.50</span>), (<span class="number">0.01</span>, <span class="number">1</span>))</div><div class="line">y = signal.lfilter(b, <span class="number">1</span>, x)</div><div class="line"></div><div class="line">plt.plot(x)</div><div class="line">plt.plot(y)</div><div class="line">plt.show()</div></pre></td></tr></table></figure>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2018/02/26/ECG-Signal-Denoise/" rel="next" title="ECG Signal Denoise">
                <i class="fa fa-chevron-left"></i> ECG Signal Denoise
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2018/02/27/Fourier-Transforms-in-SciPy/" rel="prev" title="Fourier Transforms in SciPy">
                Fourier Transforms in SciPy <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/uploads/avatar.jpg"
               alt="东木金" />
          <p class="site-author-name" itemprop="name">东木金</p>
           
              <p class="site-description motion-element" itemprop="description">正在学习机器学习，希望能变得很强！</p>
          
        </div>
        <nav class="site-state motion-element">

          
            <div class="site-state-item site-state-posts">
              <a href="/archives/">
                <span class="site-state-item-count">162</span>
                <span class="site-state-item-name">日志</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-categories">
              <a href="/categories/index.html">
                <span class="site-state-item-count">18</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-tags">
              <a href="/tags/index.html">
                <span class="site-state-item-count">42</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/bdmk" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                    
                      GitHub
                    
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="mailto:catcherchan94@outlook.com" target="_blank" title="E-Mail">
                  
                    <i class="fa fa-fw fa-envelope"></i>
                  
                    
                      E-Mail
                    
                </a>
              </span>
            
          
        </div>

        
        

        
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#基础频谱分析"><span class="nav-number">1.</span> <span class="nav-text">基础频谱分析</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#频谱分析变量"><span class="nav-number">1.1.</span> <span class="nav-text">频谱分析变量</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#对噪声信号做频谱分析"><span class="nav-number">1.2.</span> <span class="nav-text">对噪声信号做频谱分析</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#fftshift"><span class="nav-number">1.3.</span> <span class="nav-text">fftshift</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#逆向快速傅里叶变换"><span class="nav-number">1.4.</span> <span class="nav-text">逆向快速傅里叶变换</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#滤波器设计"><span class="nav-number">2.</span> <span class="nav-text">滤波器设计</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#实际滤波器的设计指标"><span class="nav-number">2.1.</span> <span class="nav-text">实际滤波器的设计指标</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#FIR-滤波器简介"><span class="nav-number">2.2.</span> <span class="nav-text">FIR 滤波器简介</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#FIR-滤波器的线性相位特性"><span class="nav-number">2.2.1.</span> <span class="nav-text">FIR 滤波器的线性相位特性</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#fir1-Window-based-FIR-filter-design"><span class="nav-number">2.3.</span> <span class="nav-text">fir1: Window-based FIR filter design</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#输入参数"><span class="nav-number">2.3.1.</span> <span class="nav-text">输入参数</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#n-—-Filter-order-integer-scalar"><span class="nav-number">2.3.1.1.</span> <span class="nav-text">n — Filter order, integer scalar</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Wn-—-Frequency-constraints-scalar-two-element-vector-multi-element-vector"><span class="nav-number">2.3.1.2.</span> <span class="nav-text">Wn — Frequency constraints, scalar | two-element vector | multi-element vector</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#ftype-—-Filter-type-‘low’-‘bandpass’-‘high’-‘stop’-‘DC-0’-‘DC-1’"><span class="nav-number">2.3.1.3.</span> <span class="nav-text">ftype — Filter type, ‘low’ | ‘bandpass’ | ‘high’ | ‘stop’ | ‘DC-0’ | ‘DC-1’</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#fir2-Frequency-sampling-based-FIR-filter-design"><span class="nav-number">2.4.</span> <span class="nav-text">fir2: Frequency sampling-based FIR filter design</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Bilinear-transform"><span class="nav-number">3.</span> <span class="nav-text">Bilinear transform</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Linear-time-invariant-theory"><span class="nav-number">4.</span> <span class="nav-text">Linear time-invariant theory</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#重要的系统特性"><span class="nav-number">4.1.</span> <span class="nav-text">重要的系统特性</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#因果性"><span class="nav-number">4.1.1.</span> <span class="nav-text">因果性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#稳定性"><span class="nav-number">4.1.2.</span> <span class="nav-text">稳定性</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#离散时间系统"><span class="nav-number">4.2.</span> <span class="nav-text">离散时间系统</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#连续时间系统中的离散时间系统"><span class="nav-number">4.2.1.</span> <span class="nav-text">连续时间系统中的离散时间系统</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#冲激响应"><span class="nav-number">4.3.</span> <span class="nav-text">冲激响应</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#傅里叶分析"><span class="nav-number">5.</span> <span class="nav-text">傅里叶分析</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Fourier-series-傅里叶级数"><span class="nav-number">5.1.</span> <span class="nav-text">Fourier series 傅里叶级数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Discrete-time-Fourier-Transform"><span class="nav-number">5.2.</span> <span class="nav-text">Discrete-time Fourier Transform</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#DTFT-与-DFT"><span class="nav-number">5.2.1.</span> <span class="nav-text">DTFT 与 DFT</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Fast-Fourier-transform"><span class="nav-number">6.</span> <span class="nav-text">Fast Fourier transform</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Python-滤波器设计"><span class="nav-number">7.</span> <span class="nav-text">Python 滤波器设计</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#用-freqz-计算数字滤波器的频率响应"><span class="nav-number">7.1.</span> <span class="nav-text">用 freqz 计算数字滤波器的频率响应</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#FIR-滤波器设计"><span class="nav-number">7.2.</span> <span class="nav-text">FIR 滤波器设计</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#理想的低通滤波器"><span class="nav-number">7.2.1.</span> <span class="nav-text">理想的低通滤波器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#理想低通滤波器的近似方法"><span class="nav-number">7.2.2.</span> <span class="nav-text">理想低通滤波器的近似方法</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#用-firwin-设计滤波器"><span class="nav-number">7.2.2.1.</span> <span class="nav-text">用 firwin 设计滤波器</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#数字滤波器的计算工作"><span class="nav-number">7.3.</span> <span class="nav-text">数字滤波器的计算工作</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#滤波器级联"><span class="nav-number">7.4.</span> <span class="nav-text">滤波器级联</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#将低通滤波器和高通滤波器级联为带通滤波器"><span class="nav-number">7.4.1.</span> <span class="nav-text">将低通滤波器和高通滤波器级联为带通滤波器</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#对采用频率为1000hz的信号做滤波处理"><span class="nav-number">7.5.</span> <span class="nav-text">对采用频率为1000hz的信号做滤波处理</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy;  2017 - 
  <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">东木金</span>
</div>


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Gemini
  </a>
</div>


        

        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.2"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.2"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.2"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.2"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.2"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.2"></script>



  


  




	





  





  






  

  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'manual') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>





  

  

  

  
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


  

  

</body>
</html>
